/**
 * MongoDB reference : http://docs.mongodb.org/manual/reference/operator/
 * MongoLab API reference : https://support.mongolab.com/entries/20433053-Is-there-a-REST-API-for-MongoDB-
 */

function DB(parameters) {
    parameters = Util.getObject(parameters);

    this.database = Util.checkStringNotEmpty(parameters.database) ? parameters.database : DB.database;
    this.collection = Util.checkStringNotEmpty(parameters.collection) ? parameters.collection : undefined;

}

DB.apiKey = '50d5f8d8e4b078304a66dd79';
DB.baseUrl = 'https://api.mongolab.com/api/1/';
DB.database = 'btc';

DB.get = function(uri, parameters, callback, method) {
    if (!Util.checkStringNotEmpty(method)) {
        method = 'POST';
    }
    $.ajax({
        type : method,
        contentType: "application/json;charset=utf-8",
        url : DB.baseUrl + uri + '?apiKey=' + DB.apiKey,
        data : parameters,
        success: function(data) {
            Util.getFunction(callback)(data);
        }
    });
};

DB.getDatabaseMap = function(callback) {
    DB.get('databases', {}, function(data) {
        Util.getFunction(callback)(data);
    });
};

DB.getCollectionMap = function(database, callback) {
    DB.get('databases/' + database + '/collections', {}, function(data) {
        Util.getFunction(callback)(data);
    });
};

DB.prototype.exec = function(parameters, callback, method) {
    DB.get('databases/' + this.database + '/collections/' + this.collection, parameters, function(data) {
        Util.getFunction(callback)(data);
    }, method);
};

DB.prototype.find = function(id, callback) {
    DB.get('databases/' + this.database + '/collections/' + this.collection + '/' + Util.getString(id), {}, function(data) {
        Util.getFunction(callback)(data);
    }, 'GET');
};

DB.prototype.findAll = function(parameters, callback) {
    parameters['q'] = Util.checkObject(parameters['q']) ? JSON.stringify(parameters['q']) : undefined;
    parameters['s'] = Util.checkObject(parameters['s']) ? JSON.stringify(parameters['s']) : undefined;
    parameters['sk'] = Util.checkNumber(parameters['sk']) ? parameters['sk'] : undefined;
    parameters['l'] = Util.checkNumber(parameters['l']) ? parameters['l'] : undefined;
    DB.get('databases/' + this.database + '/collections/' + this.collection, parameters, function(data) {
        Util.getFunction(callback)(data);
    }, 'GET');
};

DB.prototype.findOne = function(query, callback) {
    var parameters = {};
    parameters['q'] = Util.checkObject(query) ? JSON.stringify(query) : undefined;
    parameters['fo'] = true;
    DB.get('databases/' + this.database + '/collections/' + this.collection, parameters, function(data) {
        Util.getFunction(callback)(data);
    }, 'GET');
};

DB.prototype.save = function(object, callback) {
    Util.assertThrow(Util.checkObject(object), true, 'Argument should be an object');
    // Insert
    if (!Util.checkObject(object._id)) {
        DB.get('databases/' + this.database + '/collections/' + this.collection, JSON.stringify(object), function(data) {
            Util.getFunction(callback)(data);
        }, 'POST');
    }
    // Update
    else {
        var id = object._id.$oid;
        object._id = undefined;
        DB.get('databases/' + this.database + '/collections/' + this.collection + '/' + id, JSON.stringify({'$set' : object}), function(data) {
            Util.getFunction(callback)(data);
        }, 'PUT');
    }
};

DB.prototype.delete = function(arg, callback) {
    var id = undefined;
    if (Util.checkStringNotEmpty(arg)) {
        id = arg;
    } else if(Util.checkObject(arg) && Util.checkObject(arg._id)) {
        id = arg._id.$oid;
    } else {
        return;
    }
    DB.get('databases/' + this.database + '/collections/' + this.collection + '/' + id, {}, function(data) {
        Util.getFunction(callback)(data);
    }, 'DELETE');
};